iT邦幫忙

0

觀察EF Core 載入模式之測試筆記

miy 2019-03-27 10:48:192443 瀏覽
  • 分享至 

  • xImage
  •  

這是篇觀察EF Core執行時行為的測試筆記,若有謬誤繁請指正/images/emoticon/emoticon02.gif

model結構 => Song與SongRecord為一對多

public class Song: BaseField
{
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { set; get; }
        public string Name { set; get; }
        public string Descrption { set; get; }  
        public virtual ICollection<SongRecord> SongRecords { set; get; }

        public Song()
        {
            this.SongRecords = new List<SongRecord>();
        }
}
public class SongRecord : BaseField
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { set; get; }
    [ForeignKey("Song")]
    public int SongId { set; get; }
    public DateTime Time { set; get; }
    public string Listener { set; get; }
    public string SongUrl { set; get; }

    public virtual Song Song { set; get; }
}

1.消極式載入(Lazy loading)

1.1、若直接取回實體,由於消極式載入機制,其關聯的SongRecords欄位為空

var lazy_q = Context.Songs;
var lazy_m = lazy_q.ToList();

觀察變數lazy_m:https://ithelp.ithome.com.tw/upload/images/20190327/20106340jE3fVpG0LF.png

1.2、變數lazy_m已是toList後的實體, SongRecords依舊為空

var lazy_child_t = lazy_m.SelectMany(x=>x.SongRecords).ToList();

觀察變數lazy_child_t:https://ithelp.ithome.com.tw/upload/images/20190327/20106340dz3hKed2W4.png

1.3、在這裡使用到了 SongRecords欄位,則取回實體後, SongRecords欄位有值

var lazy_child_q = lazy_q.SelectMany(y => y.SongRecords);
var lazy_child_m = lazy_child_q.ToList();

觀察變數lazy_child_m:https://ithelp.ithome.com.tw/upload/images/20190327/201063401jFaYNKmDK.png

1.4、執行到此,回頭看上面的變數 lazy_m ,由於預設行為會進行tracking, 變數lazy_m偵測到變數 lazy_child_m 取回了 SongRecords 的資料,則其 SongRecords欄位會被填入值
觀察變數lazy_m:https://ithelp.ithome.com.tw/upload/images/20190327/20106340d5gQnCfWEU.png

1.5、若不想進行tracking,則呼叫AsNoTracking()方法,取回的實體便是單純的實體,不會發生(第1.4節)的行為

var lazy_m = lazy_q.AsNoTracking().ToList();

驗證了官網描述,當呼叫了導覽屬性,才會從sql取回其資料

2.積極式載入(Eager loading)

指定 SongRecords欄位後取回實體,將一併取回包含 SongRecords欄位的所有資料

var eager_q = Context.Songs.Include(x => x.SongRecords);
var eager_m = eager_q.ToList();

觀察變數eager_m:https://ithelp.ithome.com.tw/upload/images/20190327/20106340d5gQnCfWEU.png

明確知道需要甚麼資料時可以使用此模式,一次性取回資料,減少與資料庫的往返次數

3.明確式載入(Explicit loading)

在明確需要實體時呼叫load(),以明確載入實體

var song = Context.Songs.FirstOrDefault();

觀察變數song:https://ithelp.ithome.com.tw/upload/images/20190327/20106340jE3fVpG0LF.png

執行後,欄位 SongRecords的實體資料被填入,注意必須在tracking的狀態才能使用load()

Context.Entry(song).Collection(x => x.SongRecords).Query().Load();

觀察變數song:https://ithelp.ithome.com.tw/upload/images/20190327/20106340d5gQnCfWEU.png


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言